package com.example.dao.impl; // 定义包名，表示该类属于dao.impl包

import com.example.dao.UserDao; // 导入UserDao接口
import com.example.model.User; // 导入User实体类

import java.sql.*; // 导入所有SQL相关的类
import java.util.ArrayList; // 导入ArrayList集合类
import java.util.List; // 导入List接口

/**
 * UserDao接口的JDBC实现
 * 使用JDBC操作数据库实现用户数据访问
 */
public class UserDaoJdbcImpl implements UserDao { // 定义UserDaoJdbcImpl类，实现UserDao接口
    
    private static final String DB_URL = "jdbc:mysql://localhost:3306/user_system?useSSL=false&serverTimezone=UTC"; // 数据库连接URL常量
    private static final String DB_USER = "root"; // 数据库用户名常量
    private static final String DB_PASSWORD = "password"; // 数据库密码常量
    
    // SQL语句
    private static final String SELECT_BY_USERNAME = "SELECT * FROM users WHERE username = ?"; // 根据用户名查询的SQL语句常量
    private static final String INSERT_USER = "INSERT INTO users (username, password, email) VALUES (?, ?, ?)"; // 插入用户的SQL语句常量
    private static final String SELECT_ALL = "SELECT * FROM users"; // 查询所有用户的SQL语句常量
    private static final String SELECT_BY_ID = "SELECT * FROM users WHERE id = ?"; // 根据ID查询的SQL语句常量
    private static final String UPDATE_USER = "UPDATE users SET username = ?, password = ?, email = ? WHERE id = ?"; // 更新用户的SQL语句常量
    private static final String DELETE_USER = "DELETE FROM users WHERE id = ?"; // 删除用户的SQL语句常量
    
    /**
     * 获取数据库连接
     */
    private Connection getConnection() throws SQLException { // 私有方法，用于获取数据库连接
        try { // 尝试加载驱动和建立连接
            Class.forName("com.mysql.cj.jdbc.Driver"); // 加载MySQL JDBC驱动类
            return DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD); // 使用DriverManager获取数据库连接
        } catch (ClassNotFoundException e) { // 捕获驱动类未找到异常
            throw new SQLException("MySQL JDBC Driver not found", e); // 抛出SQL异常，包装原始异常
        } // try-catch结束
    } // getConnection方法结束
    
    /**
     * 从ResultSet中构建User对象
     */
    private User buildUserFromResultSet(ResultSet rs) throws SQLException { // 私有方法，从结果集构建User对象
        return new User( // 创建并返回新的User对象
            rs.getInt("id"), // 从结果集获取id字段值
            rs.getString("username"), // 从结果集获取username字段值
            rs.getString("password"), // 从结果集获取password字段值
            rs.getString("email") // 从结果集获取email字段值
        ); // User构造函数调用结束
    } // buildUserFromResultSet方法结束
    
    @Override // 重写接口方法
    public User findByUsername(String username) { // 根据用户名查找用户的实现方法
        try (Connection conn = getConnection(); // 使用try-with-resources获取数据库连接
             PreparedStatement stmt = conn.prepareStatement(SELECT_BY_USERNAME)) { // 创建预编译语句对象
            
            stmt.setString(1, username); // 设置第一个参数为用户名
            ResultSet rs = stmt.executeQuery(); // 执行查询并获取结果集
            
            if (rs.next()) { // 如果结果集有下一行数据
                return buildUserFromResultSet(rs); // 构建并返回User对象
            } // if语句结束
            
        } catch (SQLException e) { // 捕获SQL异常
            System.err.println("Error finding user by username: " + e.getMessage()); // 打印错误信息
        } // try-catch结束
        return null; // 未找到用户或发生异常时返回null
    } // findByUsername方法结束
    
    @Override // 重写接口方法
    public boolean register(User user) { // 用户注册的实现方法
        // 检查用户名是否已存在
        if (findByUsername(user.getUsername()) != null) { // 调用findByUsername方法检查用户名是否存在
            return false; // 用户名已存在，返回false
        } // if语句结束
        
        try (Connection conn = getConnection(); // 使用try-with-resources获取数据库连接
             PreparedStatement stmt = conn.prepareStatement(INSERT_USER, Statement.RETURN_GENERATED_KEYS)) { // 创建预编译语句，设置返回生成的主键
            
            stmt.setString(1, user.getUsername()); // 设置第一个参数为用户名
            stmt.setString(2, user.getPassword()); // 设置第二个参数为密码
            stmt.setString(3, user.getEmail()); // 设置第三个参数为邮箱
            
            int affectedRows = stmt.executeUpdate(); // 执行更新操作并获取影响的行数
            
            if (affectedRows > 0) { // 如果有行被影响（插入成功）
                // 获取生成的ID
                ResultSet generatedKeys = stmt.getGeneratedKeys(); // 获取生成的主键结果集
                if (generatedKeys.next()) { // 如果有生成的主键
                    user.setId(generatedKeys.getInt(1)); // 将生成的ID设置到user对象中
                } // if语句结束
                return true; // 注册成功，返回true
            } // if语句结束
            
        } catch (SQLException e) { // 捕获SQL异常
            System.err.println("Error registering user: " + e.getMessage()); // 打印错误信息
        } // try-catch结束
        return false; // 注册失败，返回false
    } // register方法结束
    
    @Override // 重写接口方法
    public List<User> findAll() { // 查找所有用户的实现方法
        List<User> users = new ArrayList<>(); // 创建用户列表用于存储结果
        
        try (Connection conn = getConnection(); // 使用try-with-resources获取数据库连接
             PreparedStatement stmt = conn.prepareStatement(SELECT_ALL); // 创建预编译语句对象
             ResultSet rs = stmt.executeQuery()) { // 执行查询并获取结果集
            
            while (rs.next()) { // 遍历结果集中的每一行
                users.add(buildUserFromResultSet(rs)); // 构建User对象并添加到列表中
            } // while循环结束
            
        } catch (SQLException e) { // 捕获SQL异常
            System.err.println("Error finding all users: " + e.getMessage()); // 打印错误信息
        } // try-catch结束
        
        return users; // 返回用户列表
    } // findAll方法结束
    
    @Override // 重写接口方法
    public User findById(int id) { // 根据ID查找用户的实现方法
        try (Connection conn = getConnection(); // 使用try-with-resources获取数据库连接
             PreparedStatement stmt = conn.prepareStatement(SELECT_BY_ID)) { // 创建预编译语句对象
            
            stmt.setInt(1, id); // 设置第一个参数为用户ID
            ResultSet rs = stmt.executeQuery(); // 执行查询并获取结果集
            
            if (rs.next()) { // 如果结果集有下一行数据
                return buildUserFromResultSet(rs); // 构建并返回User对象
            } // if语句结束
            
        } catch (SQLException e) { // 捕获SQL异常
            System.err.println("Error finding user by id: " + e.getMessage()); // 打印错误信息
        } // try-catch结束
        return null; // 未找到用户或发生异常时返回null
    } // findById方法结束
    
    @Override // 重写接口方法
    public boolean update(User user) { // 更新用户信息的实现方法
        try (Connection conn = getConnection(); // 使用try-with-resources获取数据库连接
             PreparedStatement stmt = conn.prepareStatement(UPDATE_USER)) { // 创建预编译语句对象
            
            stmt.setString(1, user.getUsername()); // 设置第一个参数为用户名
            stmt.setString(2, user.getPassword()); // 设置第二个参数为密码
            stmt.setString(3, user.getEmail()); // 设置第三个参数为邮箱
            stmt.setInt(4, user.getId()); // 设置第四个参数为用户ID
            
            int affectedRows = stmt.executeUpdate(); // 执行更新操作并获取影响的行数
            return affectedRows > 0; // 如果有行被影响则返回true，否则返回false
            
        } catch (SQLException e) { // 捕获SQL异常
            System.err.println("Error updating user: " + e.getMessage()); // 打印错误信息
        } // try-catch结束
        return false; // 更新失败，返回false
    } // update方法结束
    
    @Override // 重写接口方法
    public boolean delete(int id) { // 删除用户的实现方法
        try (Connection conn = getConnection(); // 使用try-with-resources获取数据库连接
             PreparedStatement stmt = conn.prepareStatement(DELETE_USER)) { // 创建预编译语句对象
            
            stmt.setInt(1, id); // 设置第一个参数为用户ID
            int affectedRows = stmt.executeUpdate(); // 执行删除操作并获取影响的行数
            return affectedRows > 0; // 如果有行被影响则返回true，否则返回false
            
        } catch (SQLException e) { // 捕获SQL异常
            System.err.println("Error deleting user: " + e.getMessage()); // 打印错误信息
        } // try-catch结束
        return false; // 删除失败，返回false
    } // delete方法结束
} // UserDaoJdbcImpl类结束